package com.blog.util;

import com.blog.pojo.MLogin;
import com.google.common.collect.Lists;

import  org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
import org.codehaus.jackson.type.JavaType;
import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.List;

public class JsonUtil {
	
	private static Logger log = LoggerFactory.getLogger(JsonUtil.class);
	 
    private static ObjectMapper objectMapper = new ObjectMapper();
    static{
        //对象的所有字段全部列入
        objectMapper.setSerializationInclusion(Inclusion.ALWAYS);

        //取消默认转换timestamps形式
        objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS,false);

        //忽略空Bean转json的错误
        objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS,false);

        //所有的日期格式都统一为以下的样式，即yyyy-MM-dd HH:mm:ss
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
 
        //忽略 在json字符串中存在，但是在java对象中不存在对应属性的情况。防止错误
        objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,false);
    }
    
    
    
    
    //对象 --> json
    public static <T> String obj2String(T obj){
        if(obj == null){
            return null;
        }
        try {
            return obj instanceof String ? (String)obj :  objectMapper.writeValueAsString(obj);
        } catch (Exception e) {
            log.warn("Parse Object to String error",e);
            return null;
        }
    }
    
    
    //对象 --> json , 这个方法也是将 对象转为json的,并且格式已经格式化好了,容易看,调试的时候可以用这个
    public static <T> String obj2StringPretty(T obj){
        if(obj == null){
            return null;
        }
        try {
            return obj instanceof String ? (String)obj :  objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (Exception e) {
            log.warn("Parse Object to String error",e);
            return null;
        }
    }




    // json  --> 对象
    public static <T> T string2Obj(String str,Class<T> clazz){
        if(StringUtils.isEmpty(str) || clazz == null){
            return null;
        }
        
        
        try {
            return clazz.equals(String.class)? (T)str : objectMapper.readValue(str,clazz);
        } catch (Exception e) {
            log.warn("Parse String to Object error",e);
            return null;
        }
    }


    //下面的两个方法功能是一样的,所传参数不同, 都是讲 json 数据 转为对象, 对象是 list, set ,map这样的类型并带又泛型. 
    public static <T> T string2Obj(String str, TypeReference<T> typeReference){
        if(StringUtils.isEmpty(str) || typeReference == null){
            return null;
        }
        try {
            return (T)(typeReference.getType().equals(String.class)? str : objectMapper.readValue(str,typeReference));
        } catch (Exception e) {
            log.warn("Parse String to Object error",e);
            return null;
        }
    }


    public static <T> T string2Obj(String str,Class<?> collectionClass,Class<?>... elementClasses){
        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass,elementClasses);
        try {
            return objectMapper.readValue(str,javaType);
        } catch (Exception e) {
            log.warn("Parse String to Object error",e);
            return null;
        }
    }


    //测试

    public static void main(String[] args) {
       
    	
        //**************
        //obj --> json
    	MLogin user = new MLogin();
        user.setId(1);
        user.setName("lm");
        user.setPassword("123456");
        
        MLogin user2 = new MLogin();
        user2.setId(2);
        user2.setName("lm2");
        user2.setPassword("654321s");
        
        String json = JsonUtil.obj2StringPretty(user);
        String json2 = JsonUtil.obj2String(user);
        
//        log.info("对象转为json，格式美观：{}",json);
        log.info("对象转为json，格式不美观：{}",json2);
        
 
        //**************
        //json --> obj
        
        MLogin loginUser = JsonUtil.string2Obj(json2, MLogin.class);
        log.info("json转为对象:\n{}",loginUser.toString());
        
        
       //**************
       // list对象 --> json
        
        List<MLogin> userList = Lists.newArrayList();
        userList.add(user);
        userList.add(user2);
        
        String userListStr = JsonUtil.obj2String(userList);
        log.info("将list对象转为json:\n{}",userListStr );
        
        //**************
        // json对象 --> list
        
        //第一种方法
        List<MLogin> userListObj1 = JsonUtil.string2Obj(userListStr, new TypeReference<List<MLogin>>() {
        }); 
        log.info("将json对象转为list对象 , 方法1:\n{}",userListObj1 );
        
        
        //第二种方法
        List<MLogin> userListObj2 = JsonUtil.string2Obj(userListStr,List.class,MLogin.class);
        log.info("将json对象转为list对象 方法2:\n{}",userListObj2 );
        
        	
    }





}
